const mongodb = require('mongodb');

const getdb = require('../utils/database').getdb;

const ObjectId = mongodb.ObjectId;

module.exports = class User {
    constructor(id, name, email, cart) {
        this._id = id;
        this.name = name;
        this.email = email;
        this.cart = cart;
    }
    save() {
        return getdb().collection('users')
        .insertOne(this)
    }
    static findById(userId) {
        return getdb().collection('users')
        .findOne({ _id: new ObjectId(userId) })
    }
    addToCart(prodId) {
        const findFetchProdIndex = this.cart.items.findIndex(item => item.prodId.toString() === prodId);
        if (findFetchProdIndex !== -1) {
            let item = this.cart.items[findFetchProdIndex];
            item.quantity += 1;
        } else {
            this.cart.items.push({
                prodId: new ObjectId(prodId),
                quantity: 1
            })
        }
        return getdb().collection('users')
        .updateOne(
            { _id: this._id },
            { 
                $set: { cart: this.cart }
            }
        )
    }
    getCart() {
        const prodIds = this.cart.items.map(item => item.prodId);
        return getdb().collection('products')
        .find({ _id: { $in: prodIds } })
        .toArray()
        .then(products => {
            return products.map(prod => {
                return {
                    ...prod,
                    quantity: this.cart.items.find(item => item.prodId.toString() === prod._id.toString()).quantity
                }
            })
        })
    }
    deleteFromCart(prodId) {
        const newItems = this.cart.items.filter(item => item.prodId.toString() !== prodId)
        this.cart.items = newItems;
        return getdb().collection('users')
        .updateOne(
            { _id: this._id },
            { $set: { cart: this.cart } }
        )
    }
    addOrder() {
        const newOrder = {
            user: {
                id: this._id,
                name: this.name
            }
        }
        return this.getCart()
        .then(products => {
            newOrder.items = products;
            newOrder.totalPrice = products.reduce((pre, prod) =>{
                return pre + prod.quantity * prod.price
            }, 0)
            return getdb().collection('orders')
            .insertOne(newOrder)
        })
        .then(result => {
            this.cart = { items: [] };
            return getdb().collection('users')
            .updateOne(
                { _id: this._id },
                { 
                    $set: { cart: this.cart }
                }
            )
        })
    }
    getOrders() {
        return getdb().collection('orders')
        .find({ 'user.id': this._id })
        .toArray()
    }
}